package admin

import (
	"center/db"
	"center/db/models"
	"common/macaroon"
	uuid2 "common/uuid"
	"github.com/gorilla/mux"
	"go.uber.org/zap"
	"golang.org/x/crypto/bcrypt"
	"net/http"
)

func (server *Server) addUser(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	var input struct {
		Username string `json:"username" validate:"omitempty"`
		Email    string `json:"email" validate:"required,email"`
		Password string `json:"password" validate:"required"`
	}

	err := bind(r, &input)
	if err != nil {
		server.log.Error("addUser.bind error", zap.Error(err))
		server.sendJSONError(w, "failed to unmarshal request",
			err.Error(), http.StatusBadRequest)
		return
	}

	if _t, _err := server.db.ExistsUserByEmail(ctx, input.Email); _t || _err != nil {
		server.sendJSONError(w, "user exists",
			"", http.StatusBadRequest)
		return
	}

	pass, err := bcrypt.GenerateFromPassword([]byte(input.Password), 0)
	if err != nil {
		server.sendJSONError(w, "server error",
			err.Error(), http.StatusInternalServerError)
		return
	}

	kmsRes, err := server.kmsClient.CreateKey()
	if err != nil {
		server.log.Error("kms创建keyid失败", zap.Error(err))
		server.sendJSONError(w, "server error",
			err.Error(), http.StatusInternalServerError)
		return
	}
	uuid, err := uuid2.FromString(kmsRes.Result.Keyid)
	if err != nil {
		server.log.Error("kms创建uuid失败", zap.Error(err))
		server.sendJSONError(w, "server error",
			err.Error(), http.StatusInternalServerError)
		return
	}

	var user *models.User
	user, err = server.db.CreateUser(ctx, &db.CreateUserParam{
		ID:           uuid,
		Username:     input.Username,
		Email:        input.Email,
		PasswordHash: pass,
	})

	if err != nil {
		server.sendJSONError(w, "server error",
			err.Error(), http.StatusInternalServerError)
		return
	}

	apikey, err := macaroon.NewAPIKey(user.ID, user.SecretKey)
	if err != nil {
		server.log.Error("生成apikey失败", zap.Error(err))
		server.sendJSONError(w, "server error",
			err.Error(), http.StatusInternalServerError)
		return
	}

	server.sendJSONData(w, http.StatusOK, struct {
		*models.User
		ApiKey string `json:"api_key"`
	}{
		user,
		apikey.Serialize(),
	})
}

func (server *Server) userInfo(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	vars := mux.Vars(r)
	userEmail, ok := vars["useremail"]
	if !ok {
		server.sendJSONError(w, "user-email missing",
			"", http.StatusBadRequest)
		return
	}

	user, err := server.db.GetUserByEmail(ctx, userEmail)

	if err != nil {
		server.sendJSONError(w, "server error",
			err.Error(), http.StatusInternalServerError)
		return
	}

	apikey, err := macaroon.NewAPIKey(user.ID, user.SecretKey)
	if err != nil {
		server.log.Error("生成apikey失败", zap.Error(err))
		server.sendJSONError(w, "server error",
			err.Error(), http.StatusInternalServerError)
		return
	}

	server.sendJSONData(w, http.StatusOK, struct {
		*models.User
		ApiKey string `json:"api_key"`
	}{
		user,
		apikey.Serialize(),
	})
}
